//
//  HRVChartView.swift
//  DaRings
//
//  Created by HFY on 2022/11/13.
//

import UIKit
import MYModule
import RxSwift
import RxCocoa


public class HRVChartView: View {
    
    public private(set) var selectIndex = PublishSubject<Int?>()
    
    let verticalStackView = TitleStackView()
    let horizontalStackView = TitleStackView()
    
    let gridView = GridView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 92.0, height: 103))
    
    let pathView = PathView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 92.0, height: 103))
    
    
    var hrvDatas: [HRVChartData]? {
        
        didSet {
            
            guard let hrvDatas = hrvDatas else {
                return
            }
            
            
            let numbers = verticalStackViewTitles(of: hrvDatas)
            
            verticalStackView.titles = numbers.map { "\($0)" }
            // 最大值
            pathView.max = numbers.first ?? 150
            
            pathView.hrvs = hrvDatas
            
        }
    }
    
    public func slider(_ point: CGPoint) {
        
        self.layoutIfNeeded()
        
        debugPrint("point = \(point)")
        
        var chartPoint = self.convert(point, to: gridView)
        let width = gridView.frame.width
        
        chartPoint.x = chartPoint.x - gridView.frame.minX
        
        if chartPoint.x < 0 {
            selectIndex.onNext(nil)
            return
            
        }
        
        guard let barData = hrvDatas, !barData.isEmpty else {
            selectIndex.onNext(nil)
            return
        }
        
        if chartPoint.x > width {
            chartPoint.x = width
        }
        
        var x = chartPoint.x
        let barWidth = width/CGFloat(gridView.horizontalLines.count)
        let trun = x.truncatingRemainder(dividingBy: barWidth)
        
        if trun > 0 {
            x = chartPoint.x - trun + barWidth
        }
        
        let location: Int = Int(x/width * CGFloat(gridView.horizontalLines.count))
        
        debugPrint("point = \(chartPoint), width = \(width), location = \(location)")
        
        selectIndex.onNext(location)
        
    }
    
    
    
    public override func makeUI() {
        super.makeUI()
        verticalStackView.axis = .vertical
        verticalStackView.alignment = .trailing
        verticalStackView.textColor = UIColor.assist_D0D0D0
        
        horizontalStackView.axis = .horizontal
        horizontalStackView.alignment = .top
        horizontalStackView.font = Fonts.systemFont(ofSize: 11)
        horizontalStackView.titles = ["00:00", "06:00", "12:00", "18:00", "24:00"]
        
        addSubview(verticalStackView)
        addSubview(horizontalStackView)
        addSubview(gridView)
        addSubview(pathView)
        
        gridView.snp.makeConstraints { make in
            make.left.equalTo(26)
            make.right.equalTo(-6)
            make.top.equalToSuperview()
            make.bottom.equalTo(-18.5)
        }
        
        pathView.snp.makeConstraints { make in
            make.edges.equalTo(gridView)
        }
        
        verticalStackView.snp.makeConstraints { make in
            make.right.equalTo(gridView.snp.left).offset(-1)
            make.top.equalTo(gridView.snp.top)
            make.bottom.equalTo(gridView.snp.bottom)
        }
        
        horizontalStackView.snp.makeConstraints { make in
            make.left.equalTo(gridView.snp.left)
            make.right.equalTo(gridView.snp.right)
            make.top.equalTo(gridView.snp.bottom).offset(1)
        }
    }
    
    
    
    func verticalStackViewTitles(of hrvDatas: [HRVChartData]?) ->[Int] {
        
        guard let hrvDatas = hrvDatas else {
            return [150, 100, 50, 0]
        }
        
        let array = Array(hrvDatas)
        
        // 得到最大的 hrv 值
        let t = array.sorted { $0.hrv < $1.hrv }
        
        guard let last = t.last else { return [150, 100, 50, 0] }
        
        if last.hrv > 200  {
            
            return [300, 150, 0]
            
        } else if last.hrv > 150 {
            
            return [200, 100, 0]
            
        }
        
        return [150, 100, 50, 0]
        
    }
    
    
    
    
    class TitleStackView: StackView {
        
        var font: UIFont = Fonts.systemFont(ofSize: 10) {
            
            didSet {
                
                for label in self.labels {
                    label.font = font
                }
                
            }
            
        }
        var textColor: UIColor = UIColor.assist_D0D0D0 {
            
            didSet {
                
                for label in self.labels {
                    label.textColor = textColor
                }
                
            }
        }
        
        var labels: [UILabel] {
            
            return self.subviews.compactMap {
                
                return $0 as? UILabel
            }
        }
        
        
        var titles: [String]? {
            
            willSet {
                
                guard let newValue = newValue else {
                    
                    return
                    
                }
                
                if titles == newValue {
                    return
                }
                
                // 删除旧的
                for view in self.subviews {
                    view.removeFromSuperview()
                }
                
                // 添加新的
                _ = newValue.map {[weak self] (text) ->UILabel in
                    
                    let label = UILabel()
                    label.text = text
                    label.font = self?.font
                    label.textColor = self?.textColor
                    
                    self?.addArrangedSubview(label)
                    
                    return label
                }
            }
            
            
        }
        
        override func makeUI() {
            distribution = .equalSpacing
        }
    }
    
    
    class GridView: View {
        
        public var verticalLines: [UIView] = []
        public var horizontalLines: [UIView] = []
        
        public var vertical_space: CGFloat = 0 {
            
            didSet {
                
                var beforeLine: UIView?
                for line in verticalLines {
                    
                    line.snp.remakeConstraints { make in
                        
                        if let beforeLine = beforeLine {
                            make.centerX.equalTo(beforeLine.snp.centerX).offset(vertical_space)
                        } else {
                            make.centerX.equalTo(self.snp.left).offset(vertical_space)
                        }
                        
                        make.top.bottom.equalToSuperview()
                        make.width.equalTo(1.0)
                    }
                    
                    beforeLine = line
                }
            }
        }
        
        
        public var horizontal_space: CGFloat = 0 {
            
            didSet {
                
                var beforeLine: UIView?
                for line in horizontalLines {
                    
                    line.snp.remakeConstraints { make in
                        make.left.right.equalToSuperview()
                        
                        if let beforeLine = beforeLine {
                            make.centerY.equalTo(beforeLine.snp.centerY).offset(-horizontal_space)
                        } else {
                            make.bottom.equalToSuperview()
                        }
                        
                        
                        make.height.equalTo(1.0)
                    }
                    
                    beforeLine = line
                    
                }
            }
        }
        
        override func makeUI() {
            super.makeUI()
            // 每 space 画一条线
            addVertical()
            addHorizontal()
        }
        
        func addVertical() {
            
            
            for i in 1 ..< 48 {
                
                let line = UIView()
                
                
                if i%6 == 0 {
                    line.backgroundColor = UIColor.HRV.theme.withAlphaComponent(0.6)
                    
                } else {
                    line.backgroundColor = UIColor.HRV.theme.withAlphaComponent(0.3)
                    
                }
                
                addSubview(line)
                verticalLines.append(line)
                
                
                
            }
            
        }
        
        func addHorizontal() {
            
            
            for i in 0 ..< 18 {
                
                let line = UIView()
                
                
                if (i + 1)%6 == 0 && i != 17 {
                    line.backgroundColor = UIColor.HRV.theme.withAlphaComponent(0.6)
                    
                } else {
                    line.backgroundColor = UIColor.HRV.theme.withAlphaComponent(0.3)
                    
                }
                
                
                addSubview(line)
                horizontalLines.append(line)
            
            }
            
        }
        
        
        override func layoutSubviews() {
            super.layoutSubviews()
            
            if horizontal_space == 0 {
                horizontal_space = (self.frame.height - 1)/17.0
            }
            
            if vertical_space == 0 {
                // 48 条线
                vertical_space = self.frame.width/48.0
            }
        
        }
        
    }
    
    
    public class PathView: View {
        
        let pathLayer = CAShapeLayer()
        
        var arcLayers: [CAShapeLayer] = []
        
        
        var max: Int = 150
        
        var hrvs: [HRVChartData]? {
            
            didSet {
                
                guard let hrvs = hrvs else {
                    
                    if let sublayers = pathLayer.sublayers {
                        for layer in sublayers {
                            layer.removeFromSuperlayer()
                        }
                    }
                    
                    pathLayer.path = nil
                    pathLayer.setNeedsDisplay()
                    return
                }
                
                // 计算出比例
                let h_proportion = self.frame.height/CGFloat(max)
                // 横坐标，对应时间 分钟
                let w_proportion = self.frame.width/(24.0 * 60)
                
                let mutablePoints: [CGPoint?] = hrvs.map {
                    
                    let y: CGFloat = self.frame.height - CGFloat($0.hrv) * h_proportion
                    
                    let mins = $0.minute
                    let x = mins * w_proportion
                    
                    let p = CGPoint(x: x, y: y)
                    return p
                    
                }
   
                let points: [CGPoint] = mutablePoints.compactMap { $0 }
                
                let path = UIBezierPath()
                removeArcLayers()
                
                for (i, point) in points.enumerated() {
                    // 画线
                    if i == 0 {
                        path.move(to: point)
                    } else {
                        path.addLine(to: point)
                    }
                    
                    // 画点
                    let arcLayer = arcLayer()
                    let path = UIBezierPath(arcCenter: point, radius: 2, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
                    arcLayer.path = path.cgPath
                    
                }
                
                pathLayer.path = path.cgPath
                
                
            }
            
        }
        
        
        
        
        public override func makeUI() {
            super.makeUI()
            
            backgroundColor = .clear
            pathLayer.frame = self.bounds
            pathLayer.strokeColor = UIColor.HRV.theme.cgColor
            pathLayer.fillColor = UIColor.clear.cgColor
            pathLayer.lineWidth = 1.0
            pathLayer.lineCap = .round
            pathLayer.lineJoin  = .round
            layer.addSublayer(pathLayer)
        }
        
        func arcLayer() ->CAShapeLayer {
            
            let arcLayer = CAShapeLayer()
            arcLayer.frame = self.bounds
            arcLayer.strokeColor = UIColor.HRV.theme.cgColor
            arcLayer.fillColor = UIColor.HRV.theme.cgColor
            arcLayer.lineWidth = 1.0
            arcLayer.lineCap = .round
            arcLayer.lineJoin  = .round
            layer.addSublayer(arcLayer)
            
            arcLayers.append(arcLayer)
            
            return arcLayer
            
        }
        
        func removeArcLayers() {
            
            for layer in arcLayers {
                layer.removeFromSuperlayer()
            }
            
            arcLayers.removeAll()
            
        }
        
    }
    
}



